/*
题目描述
建立一个存储学生学号和成绩信息的动态链表，并参照本书例题11.8至11.11，实现这个动态链表的建立、输出、删除特定节点、插入操作。
结构体student，存储学生的学号、名字、性别和年龄，读入每个学生的所有信息，保存在结构体中，并输出。
动态链表的每个节点存储的结构体student的定义如下：
struct student {
    long num;
    float score;
    struct student * next;
};
本题较为复杂，请参考本书相应的例题进行实现。

输入
输入的前几行为链表的建立过程。每行有一个整数和一个实数，用空格隔开，分别表示学生的学号和成绩。如果读入的学号为0，说明链表的建立过程已经结束，这个学号为0的信息不存入链表。
之后的几行每行包含一个整数，表示删除学号与这个整数相等的学生信息（删除链表节点）。如果输入的整数为0，说明删除过程已经结束，且不需要处理学号为0的节点。
最后的几行每行包含一个整数和一个实数，用空格隔开，分别表示需要插入的学生学号和成绩。如果读入的学号为0，说明插入的过程已经结束，这个学号为0的信息不需要插入链表。
输入保证在任何时刻，链表中不存在有相同学号的学生，建立链表的过程中输入的学号数值保证严格递增且大于0，链表为空时不会再继续删除。输入的总行数不超过100。

输出
首先规定用以下格式输出某一时刻链表的状态：
在一行内输出当前链表的节点数n，并在接下来的n行中按顺序输出每一个节点（学生）的学号和成绩信息，用空格隔开，且成绩保留1位小数。
在链表的建立过程结束之后，输出当前链表状态；在每一次删除操作（不包括用来标记删除过程结束的学号为0的那一次）之后，输出链表状态；在每一次插入操作（不包括用来标记插入过程结束的学号为0的那一次）之后，输出链表状态。
请注意行尾输出换行。
*/

// 说实话这个难度有点大了，需要手搓链表
// 你可以在B站搜索相关视频，了解链表。
// 你一定要拿纸笔绘制链表的结构，一步步理解代码
// 从main函数开始查看所有调用函数，在图纸上绘制走一遍
// 最后尝试不靠提示自己完成所有代码

#include <stdio.h>
#include <stdlib.h>

struct student
{
    long num;
    float score;
    struct student *next;
};

// 创建结点
struct student *createNode(long num, float score)
{
    struct student *newNode = (struct student *)malloc(sizeof(struct student));
    newNode->num = num;
    newNode->score = score;
    newNode->next = NULL;
    return newNode;
}

//  删除结点
struct student *deleteNode(struct student *head, long num)
{
    if (head == NULL) return head;
    
    if (head->num == num)
    {
        struct student *temp = head;
        head = head->next;
        free(temp);
        return head;
    }

    struct student *current = head;
    while (current->next != NULL)
    {
        if (current->next->num == num)
        {
            // 不能释放current
            struct student *temp = current->next;
            current->next = current->next->next;
            free(temp);
            break;
        }
        else
        {
            current = current->next;
        }
    }
    return head;
}

// 插入结点
struct student *insertNode(struct student *head, long num, float score)
{
    if (head == NULL || head->num > num)
    {
        struct student *newNode = createNode(num, score);
        newNode->next = head;
        return newNode;
    }

    struct student *current = head;
    while (current->next != NULL)
    {
        if (current->next->num > num)
        {
            struct student *newNode = createNode(num, score);
            newNode->next = current->next;
            current->next = newNode;
            return head;
        }
        current = current->next;
    }

    current->next = createNode(num, score);

    return head;
}

// 初始化链表
struct student *buildList(long nums[], float scores[], int count)
{
    struct student *head = NULL;
    struct student *tail = NULL;

    for (int i = 0; i < count; i++)
    {
        struct student *newNode = createNode(nums[i], scores[i]);
        if (head == NULL)
        {
            head = newNode;
            tail = newNode;
        }
        else
        {
            tail->next = newNode;
            tail = newNode;
        }
    }

    return head;
}

// 打印链表
void printList(struct student *head)
{
    int length = 0;
    struct student *current = head;
    while (current != NULL)
    {
        length++;
        current = current->next;
    }
    printf("%d\n", length);
    current = head;
    while (current != NULL)
    {
        printf("%ld %.1f\n", current->num, current->score);
        current = current->next;
    }
}

int main()
{
    // 定义存储输入数据的数组
    long build_nums[100];
    float build_scores[100];
    long delete_nums[100];
    long insert_nums[100];
    float insert_scores[100];
    
    // 计数器
    int build_count = 0;
    int delete_count = 0;
    int insert_count = 0;
    
    // 一次性读取所有输入
    char line[100];
    int phase = 0;
    
    while (fgets(line, sizeof(line), stdin)) {
        if (phase == 0) {
            long num;
            float score;
            if (sscanf(line, "%ld %f", &num, &score) == 2) {
                if (num == 0) {
                    phase = 1;
                } else {
                    build_nums[build_count] = num;
                    build_scores[build_count] = score;
                    build_count++;
                }
            }
        } else if (phase == 1) {
            long num;
            if (sscanf(line, "%ld", &num) == 1) {
                if (num == 0) {
                    phase = 2;
                } else {
                    delete_nums[delete_count] = num;
                    delete_count++;
                }
            }
        } else if (phase == 2) {
            long num;
            float score;
            if (sscanf(line, "%ld %f", &num, &score) == 2) {
                if (num == 0) {
                    break;
                } else {
                    insert_nums[insert_count] = num;
                    insert_scores[insert_count] = score;
                    insert_count++;
                }
            }
        }
    }
    
    // 建立链表
    struct student *list = buildList(build_nums, build_scores, build_count);

    // 输出建立后的链表状态
    printList(list);

    // 删除节点
    for (int i = 0; i < delete_count; i++)
    {
        list = deleteNode(list, delete_nums[i]);
        printList(list);
    }

    // 插入节点
    for (int i = 0; i < insert_count; i++)
    {
        list = insertNode(list, insert_nums[i], insert_scores[i]);
        printList(list);
    }

    // 释放内存
    struct student *current = list;
    while (current != NULL)
    {
        struct student *temp = current;
        current = current->next;
        free(temp);
    }

    return 0;
}